home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / AIAT / Headers / Common / IANarrow.h < prev    next >
Encoding:
Text File  |  1998-04-16  |  2.5 KB  |  87 lines  |  [TEXT/CWIE]

  1. // IANarrow.h
  2. //    Copyright:    © 1994 - 1998 by Apple Computer, Inc., all rights reserved.
  3. //
  4. // Safe downcasting macros.
  5. //
  6. // These are needed if you use virtual inheritance (the recommended way to do
  7. // multiple inheritance in C++) and your C++ compiler does not yet support
  8. // RTTI (RunTime Type Information, aka dynamic_cast).
  9. //
  10. // Here's an example:
  11. // Suppose you have a base class called "Base". You have two
  12. // subclasses of it and then a third subclass that inherits from both
  13. // (the diamond pattern). Here are the declarations that need to be
  14. // done:
  15. // class Base {
  16. //    IADefineNarrowMethods(Base, Base);
  17. // };
  18. // class Foo : public virtual Base {
  19. //    IADefineNarrowMethods(Foo, Base);
  20. // };
  21. // class Bar : public virtual Base {
  22. //    IADefineNarrowMethods(Bar, Base);
  23. // };
  24. // class Baz : public virtual Foo, public virtual Bar {
  25. //    IADefineNarrowMethods(Baz, Base);
  26. // };
  27. //
  28. // Then in the implementation of Base, Foo, Bar, and Baz, put in:
  29. // IAImplementNarrowMethods0(Base);
  30. // IAImplementNarrowMethods1(Foo,Base);
  31. // IAImplementNarrowMethods1(Bar,Base);
  32. // IAImplementNarrowMethods2(Baz,Foo,Bar);
  33. //
  34. // Now to use the "IANarrow" method to down cast:
  35. //
  36. // Base *r = someBasePointer;
  37. // Foo *foo = Foo::IANarrow(r);
  38. // Bar *bar = Bar::IANarrow(r);
  39. // Baz *baz = Baz::IANarrow(r);
  40. //
  41. // Note that IANarrow returns NULL if the downcast failed.
  42. //
  43.  
  44. #pragma once
  45. #ifndef IANarrow_h
  46. #define IANarrow_h
  47.  
  48. #define IADefineNarrowMethods(CLASS, BASE)\
  49. static  int     IAClassID(); \
  50. static CLASS    *IANarrow(BASE *t) { return (CLASS *)t->IANarrowInternal((long)&CLASS::IAClassID); } \
  51. virtual void    *IANarrowInternal(long oid)
  52.  
  53.  
  54. #define IAImplementNarrowMethods0(CLASS) \
  55. int CLASS::IAClassID() { return 0; } \
  56. void    *CLASS::IANarrowInternal(long oid) { \
  57.   void  *rval = 0; \
  58.   if (oid == (long)&CLASS::IAClassID) \
  59.     rval = this; \
  60.   return rval; \
  61. }
  62.  
  63. #define IAImplementNarrowMethods1(CLASS,PARENT) \
  64. int CLASS::IAClassID() { return 0; } \
  65. void    *CLASS::IANarrowInternal(long oid) { \
  66.   void  *rval = 0; \
  67.   if (oid == (long)&CLASS::IAClassID) \
  68.     rval = this; \
  69.   if (!rval) \
  70.     rval = PARENT::IANarrowInternal(oid); \
  71.   return rval; \
  72. }
  73.  
  74. #define IAImplementNarrowMethods2(CLASS,PARENT1,PARENT2) \
  75. int CLASS::IAClassID() { return 0; } \
  76. void    *CLASS::IANarrowInternal(long oid) { \
  77.   void *rval = 0; \
  78.   if (oid == (long)&CLASS::IAClassID) \
  79.     rval = this; \
  80.   if (!rval) \
  81.     rval = PARENT1::IANarrowInternal(oid); \
  82.   if (!rval) \
  83.     rval = PARENT2::IANarrowInternal(oid); \
  84.   return rval; \
  85. }
  86. #endif
  87.